define([
  "views/uicomponents/controls/message-box",
  "config/internet-map",
  "proj4",
  "html2canvas",
  "config/mapviewerConfig",
], function (MessageBox, internetMaps, proj4, html2canvas, MapviewerConfig) {
  var COSTOM_WIDTH = "770px",
    COSTOM_HEIGHT = "300px",
    ORIGIN_WIDTH = "850px",
    ORIGIN_HEIGHT = "400px";
  var SERVER_TYPE_MAP = {
    "EPSG:4326": "WGS84",
    "EPSG:3857": "MERCATOR",
    "EPSG:900913": "MERCATOR",
    "EPSG:102113": "MERCATOR",
    "EPSG:910101": "GCJ02",
    "EPSG:910111": "GCJ02MERCATOR",
    "EPSG:910102": "BD",
    "EPSG:910112": "BDMERCATOR",
  };
  // 支持的大地坐标系
  var GEODETIC_COORDINATES = [4326, 910101, 910102];
  // 相等的投影坐标系（严格）
  var STRICT_SAME_PROJECTION_COORDINATES = [3857, 900913];
  // 相等的投影坐标系（不严格）
  var SAME_PROJECTION_COORDINATES = [910112, 910111].concat(
    STRICT_SAME_PROJECTION_COORDINATES
  );
  // 底图对应可以动态投影的坐标系，目前只列出了mapViewer支持的底图的坐标系
  var WELLKNOW_COORDINATES = GEODETIC_COORDINATES.concat(
    SAME_PROJECTION_COORDINATES
  );
  //动态投影支持列表（严格）
  var STRICT_DYNAMIC_PROJECTION_MAP = {
    910112: WELLKNOW_COORDINATES,
    910111: WELLKNOW_COORDINATES,
    3857: [4326].concat(STRICT_SAME_PROJECTION_COORDINATES),
    900913: [4326].concat(STRICT_SAME_PROJECTION_COORDINATES),
  };
  var UNPROJECTION_MAP = {
    910112: SAME_PROJECTION_COORDINATES,
    910111: SAME_PROJECTION_COORDINATES,
    3857: SAME_PROJECTION_COORDINATES,
    900913: SAME_PROJECTION_COORDINATES,
  };
  var COLOE_PALETTE = [
    "#f00",
    "#f90",
    "#ff0",
    "#fff",
    "#0f0",
    "#0ff",
    "#00f",
    "#90f",
    "#f0f",
    "#000",
    "#f4cccc",
    "#fce5cd",
    "#fff2cc",
    "#d9ead3",
    "#d0e0e3",
    "#cfe2f3",
    "#d9d2e9",
    "#ead1dc",
    "#444",
    "#ea9999",
    "#f9cb9c",
    "#ffe599",
    "#b6d7a8",
    "#a2c4c9",
    "#9fc5e8",
    "#b4a7d6",
    "#d5a6bd",
    "#666",
    "#e06666",
    "#f6b26b",
    "#ffd966",
    "#93c47d",
    "#76a5af",
    "#6fa8dc",
    "#8e7cc3",
    "#c27ba0",
    "#999",
    "#c00",
    "#e69138",
    "#f1c232",
    "#6aa84f",
    "#45818e",
    "#3d85c6",
    "#674ea7",
    "#a64d79",
    "#ccc",
    "#900",
    "#b45f06",
    "#bf9000",
    "#38761d",
    "#134f5c",
    "#0b5394",
    "#351c75",
    "#741b47",
    "#eee",
    "#600",
    "#783f04",
    "#7f6000",
    "#274e13",
    "#0c343d",
    "#073763",
    "#20124d",
    "#f3f3f3",
    "#4c1130",
  ];
  var viewlang = MapViewer.Lang.Others.util;
  //WMTSLayer分辨率精度
  var RESOLUTION_PRECISION = 0.001;
  var NUM_PRECISION = 3;
  var _ = require("underscore"),
    urlRegExp = new RegExp(
      "(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]"
    ),
    _acEscape = [
      "/",
      ".",
      "*",
      "+",
      "?",
      "|",
      "(",
      ")",
      "[",
      "]",
      "{",
      "}",
      "\\",
      "$",
      "^",
      "-",
    ],
    _reReplace = new RegExp("(\\" + _acEscape.join("|\\") + ")", "g"),
    _authorizeSettingMap = {
      READ: 1,
      READWRITE: 2,
      DELETE: 3,
    };
  var onlineUrl = "https://www.supermapol.com/",
    itestUrl = "https://itest.supermapol.com/";
  function xSSFilter(val) {
    if (val === null || val === undefined) {
      return;
    }
    val = val.toString();
    val = val.replace(/</g, "&lt;");
    val = val.replace(/>/g, "&gt;");
    val = val.replace(/"/g, "&quot;");
    val = val.replace(/'/g, "&#39;");
    return val;
  }
  function _newGuid(attr) {
    var Len = attr || 32;
    var guid = "";
    for (var i = 1; i < Len; i++) {
      var n = Math.floor(Math.random() * 16.0).toString(16);
      guid += n;
    }
    return guid;
  }
  function _getSubLayers(url, credential, onSuccessed, onError, that) {
    function onCompleted(getLayersInfoEventArgs) {
      var subLayers = [];

      // 子图层信息列表
      if (getLayersInfoEventArgs.result) {
        if (getLayersInfoEventArgs.result.subLayers) {
          subLayers = getLayersInfoEventArgs.result.subLayers.layers;
        }
      }
      onSuccessed(subLayers);
    }

    function onFailed(event) {
      onError && onError(event);
    }
    var options;
    if (!SuperMap.Util.isInTheSameDomain(url)) {
      options = {
        proxy: that.getRootUrl() + "apps/viewer/getUrlResource.json?url=",
      };
    }
    var getLayersInfoService = new SuperMap.REST.GetLayersInfoService(
      url,
      options
    );
    getLayersInfoService.events.on({
      processCompleted: onCompleted,
      processFailed: onFailed,
    });
    getLayersInfoService.processAsync({ credential: credential });
  }
  var geoJsonFormat = new SuperMap.Format.GeoJSON();
  //缓存变量，用来提高访问速度
  var tempAnchor = {},
    tempRootUrl = {};
  return {
    getParamsFromUrl: function (url) {
      var idx = url.indexOf("?"),
        str = url.substr(idx + 1),
        arr = str.split(/&|=|#/gi),
        keyValueObj = {};
      if (str === "") return keyValueObj;

      for (var i = 0, len = arr.length; i < len; i += 2) {
        keyValueObj[arr[i]] = decodeURI(arr[i + 1]);
      }

      return keyValueObj;
    },
    isHttps: function (url) {
      if (!url) {
        url = window.location.href;
      }
      return url.indexOf("https://") !== -1;
    },
    getRootUrl: function (url) {
      if (!url) {
        url = window.location.href;
      }
      if (tempRootUrl[url]) {
        return tempRootUrl[url];
      }
      var rootUrl = "";
      if (url.indexOf(onlineUrl) === 0) {
        rootUrl = onlineUrl;
      } else if (url.indexOf(itestUrl) === 0) {
        rootUrl = itestUrl;
      } else {
        var regExp = /\/apps|\/web|\/manager|\/developer|\/services/i, // 该正则用于取出contextPath
          index = url.search(regExp);
        var anchor = this.getAnchor(url);
        rootUrl += anchor.protocol + "//" + this.getHost(url) + "/";
        if (index > 0) {
          // 配置了上下文，iportal/iserver/iexpress/自定义，根据目前产品中可能的情况下截取上下文,正则匹配的情况可能不全
          rootUrl += url.substring(rootUrl.length, index + 1);
        }
      }
      tempRootUrl[url] = rootUrl;
      return rootUrl;
    },
    getAnchor: function (url) {
      if (tempAnchor[url]) {
        return tempAnchor[url];
      }
      var anchor = document.createElement("a");
      anchor.href = url;
      tempAnchor[url] = anchor;
      return anchor;
    },
    getHost: function (url) {
      var anchor = this.getAnchor(url);
      return anchor && anchor.host;
    },
    /**
     * 让后台对请求的数据进行一次代理，防止跨域问题
     * @param url
     * @returns {string}
     */
    getProxyUrl: function (url) {
      return (
        this.getRootUrl() +
        "apps/viewer/getUrlResource.json?url=" +
        encodeURIComponent(url)
      );
    },
    newGuid: function (attr) {
      return _newGuid(attr);
    },
    getSubLayers: function (url, credential, onSuccessed, onError) {
      _getSubLayers(url, credential, onSuccessed, onError, this);
    },
    getFeaturesBySQL: function (
      url,
      datasetNames,
      filter,
      processCompleted,
      processFailed
    ) {
      var getFeatureParam, getFeatureBySQLService, getFeatureBySQLParams;

      getFeatureParam = new SuperMap.REST.FilterParameter({
        name: datasetNames.join().replace(":", "@"),
        attributeFilter: filter || "SMID > 0",
      });
      getFeatureBySQLParams = new SuperMap.REST.GetFeaturesBySQLParameters({
        queryParameter: getFeatureParam,
        datasetNames: datasetNames,
        fromIndex: 0,
        toIndex: 100000,
        returnContent: true,
      });
      var options = {
        eventListeners: {
          processCompleted: function (getFeaturesEventArgs) {
            processCompleted && processCompleted(getFeaturesEventArgs);
          },
          processFailed: function (e) {
            processFailed && processFailed(e);
          },
        },
      };
      //iportal的代理只支持get请求，但是GetFeaturesBySQLService是post请求，搞不懂为什么
      if (!SuperMap.Util.isInTheSameDomain(url)) {
        options.proxy =
          this.getRootUrl() + "apps/viewer/getUrlResource.json?url=";
      }
      getFeatureBySQLService = new SuperMap.REST.GetFeaturesBySQLService(
        url,
        options
      );

      getFeatureBySQLService.processAsync(getFeatureBySQLParams);
    },
    queryFeaturesBySQL: function (
      url,
      credential,
      layerName,
      attributeFilter,
      fields,
      epsgCode,
      processCompleted,
      processFailed,
      startRecord,
      recordLength,
      onlyAttribute
    ) {
      var queryParam, queryBySQLParams, queryBySQLService;
      queryParam = new SuperMap.REST.FilterParameter({
        name: layerName,
        attributeFilter: attributeFilter,
      });
      if (fields) {
        //需要保留字段
        queryParam.fields = fields;
      }
      var params = {
        queryParams: [queryParam],
      };
      if (onlyAttribute) {
        params.queryOption = SuperMap.REST.QueryOption.ATTRIBUTE;
      }
      startRecord && (params.startRecord = startRecord);
      recordLength && (params.expectCount = recordLength);
      if (epsgCode) {
        params.prjCoordSys = {
          epsgCode: epsgCode,
        };
      }
      queryBySQLParams = new SuperMap.REST.QueryBySQLParameters(params);
      var options = {
        eventListeners: {
          processCompleted: processCompleted,
          processFailed: processFailed,
        },
      };
      //iportal的代理只支持get请求，但是GetFeaturesBySQLService是post请求，搞不懂为什么
      if (!SuperMap.Util.isInTheSameDomain(url)) {
        options.proxy =
          this.getRootUrl() + "apps/viewer/getUrlResource.json?url=";
      }
      queryBySQLService = new SuperMap.REST.QueryBySQLService(url, options);
      queryBySQLService.processAsync(queryBySQLParams, credential);
    },
    /**
     * 检查url地址是否符合规范
     * @param url
     * @returns {boolean}
     */
    checkUrl: function (url) {
      if (!this.isURL(url)) {
        this.showWarningMessage(
          MapViewer.Lang.View.Mapview.urlFormatError,
          3000
        );
        return false;
      } else if (
        /^http[s]?:\/\/localhost/.test(url) ||
        /^http[s]?:\/\/127.0.0.1/.test(url)
      ) {
        this.showWarningMessage(
          MapViewer.Lang.View.Mapview.dnsOrIPAddress,
          3000
        );
        return false;
      }
      return true;
    },
    isURL: function (val) {
      val = encodeURI(val);
      return urlRegExp.test(val);
    },
    /**
     * 是否布尔类型
     */
    isBoolean: function (obj) {
      return Object.prototype.toString.call(obj).slice(8, -1) === "Boolean";
    },
    /*
     * 是否Number类型
     */
    isNumber: function (obj) {
      return Object.prototype.toString.call(obj).slice(8, -1) === "Number";
    },
    /**
     * 是否数组类型
     */
    isArray: function (obj) {
      return Object.prototype.toString.call(obj).slice(8, -1) === "Array";
    },
    toDouble: function (number) {
      return number < 10 ? "0" + number : number;
    },
    /**
     * 时间戳转换成时间字符串
     *
     * @param updateTime
     *            时间戳
     * @returns {string} 时间字符串，例：2016-9-20 11:0:0
     */
    getDateTime: function (updateTime) {
      var date = new Date(updateTime);
      var year = date.getFullYear();
      var month = date.getMonth() + 1;
      var day = date.getDate();
      var hours = date.getHours();
      var minutes = date.getMinutes();
      var seconds = date.getSeconds();
      return (
        year +
        "-" +
        this.toDouble(month) +
        "-" +
        this.toDouble(day) +
        " " +
        this.toDouble(hours) +
        ":" +
        this.toDouble(minutes) +
        ":" +
        this.toDouble(seconds)
      );
    },
    /**
     * 显示提示信息
     *
     * @param {Object}
     *            消息框的参数，包含title（标题）、content（内容）、type（类型，分为：success,info,error 四种）
     * @param {Number}
     *            消息框显示的时间，时间到了自动关闭，默认为10分钟
     *
     */
    showMessage: function (options, showTime) {
      var params = {};
      params.title = (options && options.title) || "";
      params.content = (options && options.content) || "";
      params.type = (options && options.type) || "success";
      params.link = (options && options.link) || "";
      //bootstrap接口变了，error变成了danger，在此统一一下
      if (params.type === "error") {
        params.type = "danger";
      } else if (params.type === "warning") {
        //warning和info合并一种情况
        params.type = "info";
      }
      var messageBox = MessageBox.getInstance(params);
      messageBox.show(showTime);
    },
    /**
     * 更新弹窗内的内容
     * @param options
     */
    updateMessage: function (options) {
      var params = {};
      params.content = (options && options.content) || "";
      var messageBox = MessageBox.getInstance(params);
      messageBox.keepShow();
    },
    /**
     * 显示成功信息
     * @param content
     * @param showTime
     */
    showSuccessMessage: function (content, showTime) {
      var options = {
        content: content || "",
        type: "success",
      };
      this.showMessage(options, showTime);
    },
    /**
     * 显示提示信息
     * @param content
     * @param showTime
     */
    showInfoMessage: function (content, showTime) {
      var options = {
        title: "",
        content: content || "",
        type: "info",
      };
      this.showMessage(options, showTime);
    },
    /**
     * 显示警告信息
     * @param content
     * @param showTime
     */
    showWarningMessage: function (content, showTime) {
      var options = {
        content: content || "",
        type: "warning",
      };
      this.showMessage(options, showTime);
    },
    /**
     * 显示错误信息
     * @param content
     * @param showTime
     */
    showErrorMessage: function (content, showTime) {
      var options = {
        content: content || "",
        type: "danger",
      };
      this.showMessage(options, showTime);
    },
    /**
     * 关闭提示信息
     *
     */
    closeMessage: function () {
      var messageBox = MessageBox.getInstance();
      messageBox.close();
    },
    /**
     * 检查标签是否符合规则。返回值规则如下： 0:字符串为空；1:无效标签；2:超出6个；{key: 3, tags: tags}:符合规则
     */
    checkTagsRule: function (tags) {
      if (tags.trim() === "") {
        return 0;
      }
      var arrTag = tags.split(/,|，/gi);
      var strTags = "";
      var arrTags;
      for (var i = 0, len = arrTag.length; i < len; i++) {
        if (arrTag[i].trim() !== "" && strTags.indexOf(arrTag[i]) === -1) {
          strTags += arrTag[i] + ",";
        }
      }
      if (strTags.length === 0) {
        return 1;
      } else {
        strTags = strTags.substring(0, strTags.length - 1);
        arrTags = strTags.split(",");
        if (arrTags.length > 6) {
          return 2;
        } else {
          return {
            tags: arrTags,
            key: 3,
          };
        }
      }
    },
    /*
     * 从数组中删除指定的元素并返回数组,如果数组的元素为object对象，需要传入比较的关键字
     */
    removeElementFromArray: function (elem, arr, key) {
      if (typeof elem === "undefined" || typeof arr === "undefined") {
        return arr;
      }
      if (!this.isArray(arr)) {
        return arr;
      }
      for (var i = 0, len = arr.length; i < len; i++) {
        if (arr[i] === elem || arr[i][key] === elem) {
          arr.splice(i, 1);
          break;
        }
      }
    },
    /*
     * 从数组中查找指定的元素并返回索引的位置，如果数组的元素为object对象，需要传入比较的关键字。找不到则返回-1
     */
    findElementFromArray: function (elem, arr, key) {
      if (typeof elem === "undefined" || typeof arr === "undefined") {
        return -1;
      }
      if (!this.isArray(arr)) {
        return arr;
      }
      for (var i = 0, len = arr.length; i < len; i++) {
        if (arr[i] === elem || arr[i][key] === elem) {
          return i;
        }
      }
      return -1;
    },
    isLegalInputCover: function (sSearch) {
      var filterRegExp = /['\!@#\$%\^\&\*\(\)\.\=<>\?\{\}\[\]]/g;
      return !filterRegExp.test(sSearch);
    },
    // 检测输入值是否合法，有效
    isLegalInput: function (sSearch) {
      //替换HTML标记
      sSearch = xSSFilter(sSearch);
      //替换正则需要转义的部分 \n => \\n
      var asSearch = sSearch.replace(_reReplace, "\\$1").split(" "),
        sRegExpString = "^(?=.*?" + asSearch.join(")(?=.*?") + ").*$",
        filterRegExp = new RegExp(sRegExpString);
      return filterRegExp.test(sSearch);
    },
    checkAuthorizeSetting: function (authorizeSetting) {
      var result = -1;
      if (_.isArray(authorizeSetting)) {
        _.each(authorizeSetting, function (item) {
          var permitNum = _authorizeSettingMap[item.permissionType];
          if (permitNum > result) {
            result = permitNum;
          }
        });
      }
      if (result > 1) {
        return true;
      }
      return false;
    },
    /**
     * 防止XSS攻击
     *
     * @param {String}
     *            val 输入值
     * @returns {String}
     */
    XSSFilter: function (val) {
      return xSSFilter(val);
    },

    /**
     * 获取坐标类型，主要有经纬度类型及投影类型
     *
     * @param epsgCode
     * @returns {*}
     */
    getCoordinateType: function (epsgCode) {
      if (GEODETIC_COORDINATES.indexOf(epsgCode) !== -1) {
        return MapViewer.Lang.View.Modal.latitude;
      } else if (SAME_PROJECTION_COORDINATES.indexOf(epsgCode) !== -1) {
        return MapViewer.Lang.View.Modal.projection;
      } else {
        return MapViewer.Lang.View.Modal.unKnow;
      }
    },
    /**
     * 检查坐标系
     * @param mapEpsgCode 底图坐标系
     * @param epsgCode 叠加图层坐标系
     * @param strict 是否为严格模式，严格模式只支持4326及3857坐标系的互相转换
     * @returns {number} 返回检查标识，0表示完全匹配，1表示可动态投影，2表示不可动态投影但可叠加并有偏移，3表示不支持此坐标系，4表示无坐标
     */
    checkCoordinate: function (mapEpsgCode, epsgCode, strict) {
      // 检查是否可以进行动态投影
      if (epsgCode) {
        var isEpsgCodeMatch = this.isCoordinateMatch(
          mapEpsgCode,
          epsgCode,
          true
        );
        if (isEpsgCodeMatch) {
          // 坐标匹配，直接叠加
          return 0;
        } else if (strict) {
          if (
            (epsgCode === 4326 && mapEpsgCode === 3857) ||
            (mapEpsgCode === 4326 && epsgCode === 3857)
          ) {
            // 可以进行动态投影,询问用户是否进行动态投影叠加
            return 1;
          } else {
            // 不支持此坐标系
            return 3;
          }
        } else {
          // 不匹配则检查是否可以进行动态投影
          if (this.isDynamicProjection(mapEpsgCode, epsgCode, true)) {
            // 可以进行动态投影,询问用户是否进行动态投影叠加
            return 1;
          } else if (this.isDynamicProjection(mapEpsgCode, epsgCode, false)) {
            // 不能进行动态投影,叠加有偏移
            return 2;
          } else {
            // 不支持此坐标系
            return 3;
          }
        }
      } else {
        // 给出无坐标系信息的提示
        return 4;
      }
  },
    /**
     * 根据图层的动态投影信息来检查坐标系
     * @param dynamicPrjCoordSyses 图层的动态投影信息，一般从iServer发布的地图服务中获取
     * @param mapEpsgCode 底图坐标系
     * @param epsgCode 叠加图层坐标系
     * @returns {number} 返回检查标识，0表示完全匹配，1表示可动态投影，2表示不可动态投影但可叠加并有偏移，3表示不支持此坐标系，4表示无坐标
     */
     heckCoordinateByDynamicInfo: function(dynamicPrjCoordSyses, mapEpsgCode, epsgCode){
    checkCoordinateByDynamicInfo: function (
      dynamicPrjCoordSyses,
      mapEpsgCode,
      epsgCode
    ) {
      if (mapEpsgCode === epsgCode) 
    }
      if(dynamicPrjCoordSyses && dynamicPrjCoordSyses.length > 0) {
      if   var dynamicPrjCoordSys = dynamicPrjCoordSyses[0];
        if(dynamicPrjCoordSys && dynamicPrjCoordSys.type === "PCS_ALL") {
        if   var result = this.checkCoordinate(mapEpsgCode, epsgCode, true);
          if(result > 2){
          if (result > 2) his.checkCoordinate(mapEpsgCode, epsgCode, false);
        }
          return result;
          se if (dynamicPrjCoordSys && +dynamicPrjCoordSys.epsgCode === mapEpsgCode) {
        } else if (
          dynamicPrjCoordSys &&
          +dynamicPrjCoordSys.epsgCode === mapEpsgCode
        ) {
      } else {
            for(var i= 1,len = dynamicPrjCoordSyses.length;i<len;i++){
          for (var i = 1, len = dynamicPrjCoordSyses.length; i < len; i++) 
            if(dynamicPrjCoordSys && +dynamicPrjCoordSys.epsgCode === mapEpsgCode){
            if (
              dynamicPrjCoordSys &&
              +dynamicPrjCoordSys.epsgCode === mapEpsgCode
            ) {
              
            
          return this.checkCoordinate(mapEpsgCode, epsgCode, false);
      }
        se if (epsgCode !== null || epsgCode !== undefined) {
          return 3;
        e{
      } else eturn 4;
        
  },

                isDynamicProjection : function(sourceEpsgCode, destinationEpsgCode, strict) {
    isDynamicProjection: function (
      sourceEpsgCode,
      destinationEpsgCode,
      stricte] : UNPROJECTION_MAP[sourceEpsgCode];
    ) {
      var dynamicProjMap = strict
        ? STRICT_DYNAMIC_PROJECTION_MAP[sourceEpsgCode]
       
          if (dynamicProjMap.indexOf(destinationEpsgCode) !== -1) {
            return true;
          
    }
      return false;
      

                isCoordinateMatch : function(sourceEpsgCode, destinationEpsgCode, strict) {
    isCoordinateMatch: function 
      var geoCoordinates = strict ? [ 4326 ] : GEODETIC_COORDINATES;
      var geoCoordinates = strict ? [4326
      var projCoordnates = strict ? STRICT_SAME_PROJECTION_COORDINATES : SAME_PROJECTION_COORDINATES;
      var projCoordnates = strict
        ? STRICT_SAME_PROJECTION_COORDINATES
       
      if (sourceEpsgCode === destinationEpsgCode) {
          return true;
        
      // 否则判读是否属于相同的坐标系，不同的坐标系号
      var isInGeoCoor = geoCoordinates.indexOf(sourceEpsgCode) !== -1;
      isInGeoCoor = isInGeoCoor && geoCoordinates.indexOf(destinationEpsgCode) !== -1;
      isInGeoCoor =
       oor = projCoordnates.indexOf(sourceEpsgCode) !== -1;
      isInProjCoor = isInProjCoor && projCoordnates.indexOf(destinationEpsgCode) !== -1;
      isInProjCoor =
       Coor || isInProjCoor;
      

                /**
     * 叠加图层投影信息判断
     */

                judgeProjection : function(originEpsgCode, currEpsgCodes, isBaseLayer, strict) {
    judgeProjection: function (
      originEpsgCode,
      currEpsgCodes,
      isBaseLayer,
      strict
    ) {
          if (this.isArray(currEpsgCodes) && this.isProjectionMatched(originEpsgCode, currEpsgCodes, strict) === false) {
        if (
          this.isArray(currEpsgCodes) &&
          this.isProjectionMatched(originEpsgCode, currEpsgCodes, strict) ===
            false
        ) {
          return (
            viewlang.CURRENTEPSGCODE +
            originEpsgCode +
            viewlang.CHANGEDEPSGCODE +
            currEpsgCodes.join("，") +
            viewlang.NOOVERLAY
          );
        } else if (
          !this.isArray(currEpsgCodes) &&
          this.isProjectionMatched(originEpsgCode, currEpsgCodes, strict) ===LAY;
            false
        ) {
          return (
            viewlang.CURRENTEPSGCODE +
            originEpsgCode +
            viewlang.CHANGEDEPSGCODESINGLE +
            currEpsgCodes +
            viewlang.NOOVERLAY
          );
            return null;
      }
    } else {
          if (this.isArray(currEpsgCodes) && this.isProjectionMatched(originEpsgCode, currEpsgCodes, strict) === false) {
        if (
          this.isArray(currEpsgCodes) &&
          this.isProjectionMatched(originEpsgCode, currEpsgCodes, strict) ===
            false
        ) {
          return (
            viewlang.CURRENTEPSGCODE +
            originEpsgCode +
            viewlang.OVERLAYEPSGCODE +
            currEpsgCodes.join("，") +
            viewlang.NOOVERLAY
          );
        } else if (
          !this.isArray(currEpsgCodes) &&
          this.isProjectionMatched(originEpsgCode, currEpsgCodes, strict) ===LAY;
            false
        ) {
          return (
            viewlang.CURRENTEPSGCODE +
            originEpsgCode +
            viewlang.OVERLAYEPSGCODESINGLE +
            currEpsgCodes +
            viewlang.NOOVERLAY
          );
            return null;
      }
    }
  },
    /**
     * 判断投影是否兼容。
     */
     sProjectionMatched : function(originEpsgCode, checkedEpsgCodes, strict) {
    isProjectionMatched: function .getMatchedEpsgCodes(originEpsgCode, strict);
      var toBeChecked = [];
      if (this.isArray(checkedEpsgCodes)) {
          toBeChecked = checkedEpsgCodes;
    } else {
          toBeChecked.push(checkedEpsgCodes);
    }
      for (var i = 0; i < originEpsgCodes.length; i++) {
          if ($.inArray(originEpsgCodes[i], toBeChecked) !== -1) {
            return true;
          
        
      return false;
      
    /**
     * 查询匹配的epsgcode，即图层可以相互叠加的epsgcode。
     *
     * @param originCode
     * @param strict
     * @returns {Array}
     */
     etMatchedEpsgCodes : function(originCode, strict) {
    getMatchedEpsgCodes: function 
      /**
       * 之后如果还有兼容的epsgcode，可以将它们作为一个数组，放到mappedCodes里。
       */
       appedCodes.push(strict ? STRICT_SAME_PROJECTION_COORDINATES : SAME_PROJECTION_COORDINATES);
      mappedCodes.push(
        strict
          ? STRICT_SAME_PROJECTION_COORDINATES
          : SAME_PROJECTION_COORDINATES
      );
      for (var i = 0; i < mappedCodes.length; i++) {
          if (mappedCodes[i].indexOf(originCode) !== -1) {
            matched = mappedCodes[i];
          break;
          
        
      if (matched.length === 0) {
          matched.push(originCode);
        
      return matched;
      
    /*
     * wms130服务中xy坐标轴需要反转的范围，参考wiki：http://wiki.com/pages/viewpage.action?pageId=42926105
     */
     sInverseCoordinateAxis : function(epsgCode) {
    isInverseCoordinateAxis: function 10);
      if (isNaN(epsgCode)) {
          throw new Error("isNaN");
        
      if (!this.isNumber(epsgCode)) {
          throw new Error("typeError");
        
      var lonlatCRSRanges = [ [ 4001, 4999 ], [ 2738, 2758 ], [ 2044, 2045 ], [ 2081, 2083 ], [ 2085, 2086 ], [ 2093, 2093 ], [ 2096, 2098 ],
      var lonlatCRSRanges = [
        [4001, 4999],
        [2738, 2758],
        [2044, 2045],
        [2081, 2083],
        [2085, 2086],
        [2093, 2093],
        [2096, 2098],
        [2105, 2132],
        [2169, 2170],
        [2176, 2180],
        [2193, 2193],
        [2200, 2200],
        [2206, 2212],
        [2319, 2319],
        [2320, 2358],
        [2360, 2462],
        [2523, 2549],
        [2551, 2735],
        [2935, 2941],
        [2953, 2953],
        [3006, 3030],
        [3034, 3035],
        [3058, 3059],
        [3068, 3068],
        [3114, 3118],
        [3126, 3138],
        [3300, 3301],
        [3328, 3335],
        [3346, 3346],
        [3350, 3352],
        [3366, 3366
        [3416, 3416],
        [20004, 20032],
        [20064, 20092],
        [21413, 21423],
        [21473, 21483],
        [21896, 21899],
        [22171, 221772 ],
        [22181, 22187],
        [22191, 22197],
        [25884, 25884],
        [27205, 27232],
        [27391, 27398],
        [27492, 27492],
        [28402, 28432] ];
[28462, 28492],
        [30161, 30179],
        [30800, 30800],
        [31251, 31259],
        [31275, 31279],
        [31281, 31290],
        [31466, 31700],                    var i, len = lonlatCRSRanges.length, isInversed = false;
];

      var i,
        len = lonlatCRSRanges.length,
       
                    for (i = 0; i < len; i++) {
          if (epsgCode >= lonlatCRSRanges[i][0] && epsgCode <= lonlatCRSRanges[i][1]) {
        if (
          epsgCode >= lonlatCRSRanges[i][0] &&
          epsgCode <= lonlatCRSRanges[i][1]
        ) {
          break;
          
    }

                    return isInversed;
  },
    /**
     * 检查要相互叠加的wmts图层的分辨率是否相同
     *
     * @param baseLayer 基础图层
     * @param overlayLayer 叠加图层
     * @returns {Boolean} 返回是否可以叠加
     */

                isSameResolutionsWMTSLayer : function(baseLayer, overlayLayer) {
    isSameResolutionsWMTSLayer: function 

                    if (overlayLayer.CLASS_NAME === "SuperMap.Layer.WMTS") {
          var baseResolutions = baseLayer.resolutions,overlayResolutions = overlayLayer.resolutions;
        var baseResolutions = baseLayer.resolutions,
          Len = overlayResolutions.length;
        var baseLen = baseResolutions.length,
          Len);
        var minLen = Math.min(baseLen, 
        for (var i = 0; i < minLen; = baseResolutions[i], overlayResolution = overlayResolutions[i];
          var baseResolution = baseResolutions[i],
           ion,baseResolution,i)){
          if (!this.isSameResolution(overlayResolution, baseResolution, i)) 
            
          
    }
      return isSame;
  },

                /**
     * 检查叠加图层投影某一级别的分辨率是否在基础图层投影的误差范围
     *
     * @param resolution 叠加图层分辨率
     * @param baseResolution 基础图层分辨率
     */
     sSameResolution: function(resolution, baseResolution,i) {
    isSameResolution: function (resolution, baseResolution, 
      var baseDeno = Math.pow(2, i);
      numPrecision = numPrecision > 20 ? 20 : numPrecision;
      if((Number(resolution.toFixed(numPrecision)) - RESOLUTION_PRECISION / baseDeno) <= baseResolution &&
      if (
        Number(resolution.toFixed(numPrecision)) -
          RESOLUTION_PRECISION / baseDeno <=
         = baseResolution) {
        Number(resolution.toFixed(numPrecision)) +
          RESOLUTION_PRECISION / baseDeno >=
          baseResolution
      ) {
        
      return false;
      
    // ajax请求
    sendRequest : function(url, type, dataType, data, onSuccessed, onFailed) {
    sendRequest: function questSync(url, type, true, dataType, data, onSuccessed, onFailed);
      return this.sendRequestSync(
        url,
        type,
        true,
        dataType,
        data,
        onSuccessed,
        onFailed
      );
    sendRequestSync : function(url, type, async, dataType, data, onSuccessed, onFailed) {
    sendRequestSync: function (
      url,
      type,
      async,
      dataType,
      data,
      onSuccessed,
      onFailed
    ) {
      if (!SuperMap.Util.isInTheSameDomain(url)) 
        url = decodeURIComponent(url);
        url = this.getRootUrl() + "apps/viewer/getUrlResource.json?url=" + encodeURIComponent(url);
        url =
          this.getRootUrl() +
          "apps/viewer/getUrlResource.json?url=" +
         
      return $.ajax({
          url : url,
        url : type,
        type : async,
        asyncpe : dataType,
        dataTypeta,
        datass : function(data, textStatus, xhr) {
        success: function  onSuccessed(data, textStatus, xhr);
      },
        error : function(xhr, textStatus, errorThrown) {
        error: function 
              var msg = JSON.parse(xhr.responseText);
            onFailed && onFailed(msg);
            tch (e) {
              onFailed && onFailed(xhr, textStatus, errorThrown);
            
          
        },
  },
    getInternetMap: function (internetMapName) {
        var internetMap = internetMaps[internetMapName];
      // 补丁。 缩略图使用绝对地址，防止共享时地址不正确
      internetMap.thumbnail = this.getRootUrl() + internetMap.thumbnail;
      return internetMap;
      
    getColorPalette : function(){
    getColorPalette: function () 
  },

                /**
     * 改变目标面板size大小
     *
     * @param $obj
     * @param isCostomSize
     */
    changePaneSize: function($obj, isCostomSize) {
    changePaneSize: function 
      if(isCostomSize) {
      if   animateObj = {
            width: COSTOM_WIDTH,
          height: COSTOM_HEIGHT
          height: COSTOM_HEIGHT,
        se {
          animateObj = {
            width: ORIGIN_WIDTH,
          height: ORIGIN_HEIGHT
          height: ORIGIN_HEIGHT,
    }
      $obj.css(animateObj);
  },
    /**
     * 获取模拟的事件
     * @param evt
     */
    getSimulateEvent:function(evt,offsetX,offsetY,changeType){
    getSimulateEvent: function (evt, offsetX, offsetY, changeType) 
      var event;
      var clientX,clientY,x,y;
      var clientX, clientY, x, ){
      if (type === "touchend") hangedTouches;
        if(touches && touches.length > 0){
        if (touches && touches.length > 0) offsetX;
          clientY = touches[0].pageY + offsetY;
          x = evt.xy.x + offsetX;
          y = evt.xy.y + offsetY;
          touches[0].pageX = clientX;
          touches[0].pageY = clientY;
          touches[0].clientX = clientX;
          touches[0].clientY = clientY;
      }
        if(window.TouchEvent){
        if (window.TouchEvent) vent(changeType || type,evt);
          return new TouchEvent(changeType || type, 
    }else{
      } else lientX = evt.pageX + offsetX;
        clientY = evt.pageY + offsetY;
        x=evt.x + offsetX;
        x = = evt.y + offsetY;
        if(window.MouseEvent){
        if (window.MouseEvent) 
          try  event = new window.MouseEvent(changeType || type,{
            event = new window.MouseEvent(changeType || type, 
              bubbles: le:true,
              cancelable: ,
              view: nX: evt.screenX,
              screenY: evt.screenY,
              clientX: clientX,
              clientY: clientY,
              x: x,
              y: y
              y: y,
            return event
            return event;
          } catch (error) ocument.createEvent('MouseEvents');
            event = document.createEvent("MouseEvents"lse,true,window,0,evt.screenX,evt.screenY,clientX,clientY,evt.ctrlKey,evt.altKey,evt.shiftKey,evt.metaKey,evt.button,evt.relatedTarget);
            event.initMouseEvent(
              changeType || type,
              false,
              true,
              window,
              0,
              evt.screenX,
              evt.screenY,
              clientX,
              clientY,
              evt.ctrlKey,
              evt.altKey,
              evt.shiftKey,
              evt.metaKey,
              evt.button,
              evt.relatedTarget
            );
            event.y = y;
            return event;
            
      }else{
        } else vent = document.createEvent('MouseEvents');
          event = document.createEvent("MouseEvents"lse,true,window,0,evt.screenX,evt.screenY,clientX,clientY,evt.ctrlKey,evt.altKey,evt.shiftKey,evt.metaKey,evt.button,evt.relatedTarget);
          event.initMouseEvent(
            changeType || type,
            false,
            true,
            window,
            0,
            evt.screenX,
            evt.screenY,
            clientX,
            clientY,
            evt.ctrlKey,
            evt.altKey,
            evt.shiftKey,
            evt.metaKey,
            evt.button,
            evt.relatedTarget
          );
          event.y = y;
          return event;
          
        
      
    /**
     * 增加toolti提示
     * @param $el
     * @param placement
     * @param title
     * @param bsInsertCallback
     * @param bsShowCallback
     * @param bsHideCallBack
     */
    tooltip : function($el, placement, title, bsInsertCallback, bsShowCallback, bsHideCallBack) {
    tooltip: function (
      $el,
      placement,
      title,
      bsInsertCallback,
      bsShowCallback,
      bsHideCallBack
    ) {
      $el
         delay : {
          delayhow" : 100,
            show: 250
            hide: 250,
          placement : placement,
          placementtle
          title: title,ooltip', function() {
        })
        .on("shown.bs.tooltip", function llback.call(this, $el);
      }).on('show.bs.tooltip', function() {
        })
        .on("show.bs.tooltip", function ack.call(this, $el);
      }).on('hide.bs.tooltip', function() {
        })
        .on("hide.bs.tooltip", function ack.call(this, $el);
      });
        
    /**
     * 添加web图层的
     * @param mapModel
     * @param layerModels
     * @param ThemeLayerStrategy
     * @param TiledDynamicRESTLayerStrategy
     */
     ddWebLayerToMapModel:function(mapModel,layerModels,ThemeLayerStrategy,TiledDynamicRESTLayerStrategy){
    addWebLayerToMapModel: function (
      mapModel,
      layerModels,
      ThemeLayerStrategy,
      TiledDynamicRESTLayerStrategy
    ) {
      var newLayerModels = [];
      var mapEpsgCode = mapModel.get('epsgCode');
      var mapEpsgCode = mapModel.get("epsgCode"{
      for (var j = 0, len = = layerModels[j];
        if (selectModel.get("type") === "UNKNOW") {
            // 为了让addLayer添加的model都添加上
          selectModel.on('getsublayersucceed', function(selectModel) {
          selectModel.on(
            "getsublayersucceed",
            (function 
              return function() {
              return function ial = selectModel.get('credential');
                var credential = selectModel.get("credential"
                var needTransform = selectModel.needTransform;
                var strategy;
                var isRestMap = false;
                //单子图层就创建专题图层，否则就创建动态瓦片图层
                if(layerJson.subLayers && layerJson.subLayers.length === 1){
                if (layerJson.subLayers && layerJson.subLayers.length === 1) 
                  //如果用户确认添加带偏移的数据，则专题图层默认做坐标的转换，因为矢量数据可以调用iportal的接口进行坐标的转换
                  if(selectModel.isFromConfirm){
                  if (selectModel.isFromConfirm) 
                    delete selectModel.isFromConfirm;
                    
              }else{
                } else sRestMap = true;
                  strategy = new TiledDynamicRESTLayerStrategy();
              }
                layerJson.credential = credential;
                selectModel = strategy.getLayerModel(layerJson);
                selectModel.needTransform = needTransform;
                if(needTransform){
                if (needTransform) ys = selectModel.get('prjCoordSys');
                  var prjCoordSys = selectModel.get("prjCoordSys"
                  if (prjCoordSys) .originEpsgCode = prjCoordSys.epsgCode;
                    if(isRestMap){
                    if (isRestMap) ys.epsgCode = mapEpsgCode;
                  }
                    e{
                  } else electModel.originEpsgCode = mapEpsgCode;
                    if(isRestMap) {
                    if   selectModel.set('prjCoordSys',{
                      selectModel.set("prjCoordSys", 
                        epsgCode: mapEpsgCode,
                      
                    
                  
                selectModel.on('layeraddedtomap',function(){
                selectModel.on("layeraddedtomap", function () 
                  if(count === newLayerModels.length){
                  if (count === newLayerModels.length) t", newLayerModels);
                }
              });
                mapModel.addLayerModel(selectModel);
            };
              lectModel));
            })(selectModel)ubLayers();
          );
          se{
        } else (selectModel.needTransform){
          if (selectModel.needTransform) odel.get('prjCoordSys');
            var prjCoordSys = selectModel.get("prjCoordSys"
            if (prjCoordSys) .originEpsgCode = prjCoordSys.epsgCode;
              e{
            } else electModel.originEpsgCode = mapEpsgCode;
          }
        }
          selectModel.on('layeraddedtomap',function(){
          selectModel.on("layeraddedtomap", function () 
            if(count === newLayerModels.length){
            if (count === newLayerModels.length) t", newLayerModels);
              
            
          mapModel.addLayerModel(selectModel);
          
        
      
    /**
     * 从url中解析出token
     * @param url
     * @returns {{url: *, credential: *}}
     */
     arseCredential:function(url){
    parseCredential: function (url) 
      if (!url) rn;
        
      var urls = url.split('?'),credential;
      var urls = url.split("?"),
        
      if(urls[1]){
      if (urls[1]) ams = urls[1].split('&');
        var params = urls[1].split("&"ngth; i < len; i++){
        for (var i = 0, len = params.length; i < len; i++) 
          var param = params[i].split("="0] === 'token'){
          if (param[0] === "key" || param[0] === "token") [1],param[0]);
            credential = new SuperMap.Credential(param[1], 
            break;
            
      }
    }
      return {
          url: url,
        credential:credential
        credential: credential,
      
    /**
     * 将token保存到url中去
     * @param credential
     * @param url
     * @returns {*}
     */
     redentialToUrl:function(credential,url){
    credentialToUrl: function (credential, url) 
      if (credential && url) + credential.getUrlParameters();
        return url + "?"
      return url;
      
    /**
     * 转换坐标，用监听事件获得转换后的坐标
     * @param fromEpsg
     * @param toEpsg
     * @param point 点对象或者是点数组
     * @constructor
     */
    EPSGTransform: function (fromEpsg, toEpsg, point, success) {
        var newCoord;
      var from = SERVER_TYPE_MAP[fromEpsg], to = SERVER_TYPE_MAP[toEpsg];
      var from = SERVER_TYPE_MAP[fromEpsg],
       o){
      if (fromEpsg === toEpsg || !from || !to) 
        if (_.isArray(point)) 
          for(var i= 0,len=point.length;i<len;i++){
          for (var i = 0, len = point.length; i < len; i++) y};
            var coor = { x: point[i].x, y: point[i].y 
            
      }else{
        } else ewCoord = {x:point.x,y:point.y};
          newCoord = { x: point.x, y: point.y 
        if (_.isFunction(success)) {
            success.call(success, newCoord);
          
        e{
      } else ar mercator = SERVER_TYPE_MAP['EPSG:3857'], wgs84 = SERVER_TYPE_MAP['EPSG:4326'];
        var mercator = SERVER_TYPE_MAP["EPSG:3857"],
          wgs84 = SERVER_TYPE_MAP["EPSG:4326"
        if (
          (from === mercator || from === wgs84) &&
          (to === mercator || to === wgs84)
        ) {
          this.projTransform(fromEpsg, toEpsg, point, 
        } else ar convertType = from + '_' + to;
          var convertType = from + "_"pe,point,success);
          this.postTransform(convertType, point, 
        
      
    /**
     * 通过前端proj4进行投影转换
     */
    projTransform: function (fromEpsg, toEpsg, point,success) {
    projTransform: function (fromEpsg, toEpsg, point, 
      if(_.isArray(point)){
      if (_.isArray(point)) 
        for(var i= 0,len=point.length;i<len;i++){
        for (var i = 0, len = point.length; i < len; i++) point[i].x,point[i].y]);
          var coor = proj4(fromEpsg, toEpsg, [point[i].x, 
          newCoor.push({ x: coor[0], y: coor[1] 
    }else{
      } else ewCoor = proj4(fromEpsg, toEpsg, [point.x,point.y]);
        newCoor = proj4(fromEpsg, toEpsg, [point.x, 
        newCoor = { x: newCoor[0], y: newCoor[1] 
      if (_.isFunction(success)) {
          success.call(success, newCoor);
        
      
    postTransform: function (convertType, point,success) {
    postTransform: function (convertType, point, 
      var me = this,
        e){
      if (!convertType) ss.call(me,null);
        return success.call(me, 
      if(_.isArray(point)){
      if (_.isArray(point)) n=point.length;i<len;i++){
        for (var i = 0, len = point.length; i < len; i++) i].y});
          epsgArray.push({ x: point[i].x, y: point[i].y 
        e{
      } else psgArray = [{x:point.x,y:point.y}];
        epsgArray = [{ x: point.x, y: point.y 
      if(epsgArray.length === 0) {
      if   return success.call(me,null);
        return success.call(me, 
      var postData = {
          "convertType": convertType,
        convertTypeArray
        points: epsgArray,
      var url = this.getRootUrl()+"apps/viewer/coordconvert.json";
      var url = this.getRootUrl() + stData);
      this.sendRequest(encodeURI(url), "POST","json", postData,  function (success) {
      this.sendRequest(
        encodeURI(url),
        "POST",
        "json",
        postData,
        (
              if (_.isFunction(success)) {
                if(!_.isArray(point)){
              if (!_.isArray(point)) [0];
                
              success.call(me, newCoor);
              
            
          };cess));
        })(success)
      );
    /**
     * 获取pop弹窗地理位置
     * （根据feature类型：点 线（最后一个点） 面（中线点））
     * @param featureModel
     */
     etPopShowLocation: function(featureModel,mousePosition,map){
    getPopShowLocation: function (featureModel, mousePosition, map) dth;
      var geometry,
        offset = {},
        lonLat = {},
        me = this,
        
      offset.y = 0;
      if(featureModel && featureModel.getThemeType){
      if (featureModel && featureModel.getThemeType) 
        if(type === "point"){
        if (type === "point") 
          geometry = map.getLonLatFromPixel(new SuperMap.Pixel(mousePosition.x,mousePosition.y));
          geometry = map.getLonLatFromPixel(
            new SuperMap.Pixel(mousePosition.x, mousePosition.y)
          );
          if   //说明传入进来的mousePosition已经是一个坐标
            geometry = mousePosition;
            se {
              geometry = featureModel.get('geometry');
            geometry = featureModel.get("geometry"
            geometry.lat = geometry.y;
        }
          //点符号 增加y方向上的偏移
          pointRadius = featureModel.layerModel.layer.style.pointRadius || 0;
          strokeWidth = featureModel.layerModel.layer.style.strokeWidth || 10;
          offset.y =  pointRadius/2 + strokeWidth;
          offset.y = pointRadius / 
        } else if (type === "line") eModel.layerModel.layer.style.strokeWidth;
          offset.y =  strokeWidth/2 -3;
          offset.y = strokeWidth / 2 - mPixel(new SuperMap.Pixel(mousePosition.x,mousePosition.y));
          geometry = map.getLonLatFromPixel(
            new SuperMap.Pixel(mousePosition.x, mousePosition.y)
          );
          if   //说明传入进来的mousePosition已经是一个坐标
            geometry = mousePosition;
        }
          
        } else if (type === "region") atFromPixel(new SuperMap.Pixel(mousePosition.x,mousePosition.y));
          geometry = map.getLonLatFromPixel(
            new SuperMap.Pixel(mousePosition.x, mousePosition.y)
          );
          if   //说明传入进来的mousePosition已经是一个坐标
            geometry = mousePosition;
        }
          
        lonLat.lon = geometry ? geometry.lon : mousePosition.x;
        lonLat.lat = geometry ? geometry.lat : mousePosition.y;
        
      }     var marker = featureModel.get('geometry');
        var marker = featureModel.get("geometry"
        offset.y = marker.icon && marker.icon.size && marker.icon.size.h;
    }
      return {
          lonLat: lonLat,
        offset: offset
        offset: offset,
      
    /**
     * 对要素图层的所有要素进行坐标转换
     * @param oldEpsgCode
     * @param newEpsgCode
     * @param layerModel
     * @param FeatureCollection
     * @param success
     * @param isUnNeedAddToModel 是否需要将坐标转换后的要素添加到layerModel，true不需要添加并且不会改变原来feature上的坐标，false或者默认，会改变feature上的经纬度变成转换后
     * @returns {boolean}
     */
    changeFeatureLayerEpsgCode: function(oldEpsgCode,newEpsgCode,layerModel,FeatureCollection,success,isUnNeedAddToModel){
    changeFeatureLayerEpsgCode: function (
      oldEpsgCode,
      newEpsgCode,
      layerModel,
      FeatureCollection,
      success,
      isUnNeedAddToModel
    ) {
      var features = layerModel.get("features"),
        bounds = layerModel.get("bounds"
      var hasBounds =false;
      var hasBounds = sUnNeedAddToModel){
      if (bounds && !isUnNeedAddToModel) ottom || {x:bounds.left,y:bounds.bottom},
        var leftBottom = bounds.leftBottom || {
            x: bounds.left,
            y: bounds.bottom
          },
          rightTop = bounds.rightTop || { x: bounds.right, y: bounds.top 
        if (bounds) .push(leftBottom);
          points.push(rightTop);
          hasBounds = true;
      }
    }
      if(features instanceof FeatureCollection){
      if (features instanceof FeatureCollection) 
        if   var featureCollection = new FeatureCollection();
          features.each(function(feature){
          features.each(function (feature) 后的
            var featureClone = feature.clone();
            var geometry = feature.get('geometry').clone();
            var geometry = feature.get("geometry";
            featureClone.set("geometry", eClone);
            var vertices = geometry.getVertices();
            points = points.concat(vertices);
            

            features.each(function(feature){
          features.each(function (feature) 'geometry');
            var geometry = feature.get("geometry";
            points = points.concat(vertices);
        });
          
        this.EPSGTransform('EPSG:' + oldEpsgCode, 'EPSG:'+newEpsgCode, points, function(newEpsgCode, hasBounds){
        this.EPSGTransform(
          "EPSG:" + oldEpsgCode,
          "EPSG:" + newEpsgCode,
          points,
          (function (newEpsgCode, hasBounds) 
            return function (newCoors) ewCoors.length;
              var start = 0,
                
              if (hasBounds) ;
                leftBottom = newCoors[0],rightTop = newCoors[1];
                (leftBottom = newCoors[0]), (rightTop = newCoors[1])Bottom.y, rightTop.x, rightTop.y);
                bounds = new SuperMap.Bounds(
                  leftBottom.x,
                  leftBottom.y,
                  rightTop.x,
                  rightTop.y
                );
                layerModel.set("transform_bounds", 
              for(var i= start;i<len;i++){
              for (var i = start; i < len; i++) oor = newCoors[i];
                var point = points[i],
                  coor = newCoors[i];
                point.y = coor.y;
                point.calculateBounds();
                
              features = features.clone();
              if(isUnNeedAddToModel) {
              if   success && success.call(layerModel,featureCollection);
                success && success.call(layerModel, 
                  layerModel.removeAllFeatures();
                if(layerModel.mapModel.changeMapCenterSuccess){
                if (layerModel.mapModel.changeMapCenterSuccess) EpsgCode);
                  addFeaturesToModel(features, layerModel, 
                } else ayerModel.mapModel.on('mapcenterchangebybaselayer',function(){
                  layerModel.mapModel.on(
                    "mapcenterchangebybaselayer",
                    function () {
                      addFeaturesToModel(features, layerModel, 
                    }
                  
                
              
            };EpsgCode, hasBounds));
          })(newEpsgCode, hasBounds)
        );
      function addFeaturesToModel(features,layerModel,newEpsgCode){
      function addFeaturesToModel(features, layerModel, newEpsgCode) 
        var prjCoordSys = layerModel.get("prjCoordSys"
        if (prjCoordSys) .epsgCode = newEpsgCode;
      }else{
        } else ayerModel.set('prjCoordSys',{
          layerModel.set("prjCoordSys", 
            epsgCode: newEpsgCode,
          
        features.each(function(feature,index){
        features.each(function (feature, index) try');
          var geometry = feature.get("geometry"
          if (geometry.components) (geometry.components);
        }
          geometry.calculateBounds();
          layerModel.addFeature(feature,(index !== (features.length -1)));
          layerModel.addFeature(feature, index !== features.length - 1)
        success && success.call(layerModel);
    }
      function calculateComponents(components){
      function calculateComponents(components) 
        if (components) nts.components){
          if (components.components) omponents.components);
        }else{
          } else or(var i= 0,len=components.length;i<len;i++){
            for (var i = 0, len = components.length; i < len; i++) 
              if(component.components){
              if (component.components) component.components);
            }
              component.calculateBounds();
              
            
      }
        
      return true;
      
    /**
     * 浏览器是否缓存请求
     */
     acheRequest:function (isCache) {
    cacheRequest: up({cache:isCache});
      $.ajaxSetup({ cache: isCache 
    /**
     * 隐藏图层属性
     * @param fields  feature上的所有属性字段
     * @param datas   feature上的所有属性字段对应的属性值
     * @param hideProps    需要隐藏的字段
     */
     ideProperty: function (fields,datas, hideProps) {
    hideProperty: function (fields, ps.length;i<len;i++){
      for (var i = 0, len = hideProps.length; i < len; i++) 
        var idx = _.findIndex(fields,function (val){
        var idx = _.findIndex(fields, function (val) 
          return field === hideProp;
          
        f(idx !== -1){
        if (idx !== -1) = fields[idx];
          fields.splice(idx,1);
          fields.splice(idx, f Array) {
          if   try{
            try  //属性表传过来的是feature数组的属性值
              _.each(datas,function (data) {
              _.each(datas, ce(idx,1);
                data.splice(idx, 
              });(e){
            } catch (e) {se {
              try{
            try  delete datas[field];
              ch(e){
            } catch (e) {
          
        
      
    /**
     * 将marker以及要素图层创建的元素的属性转为标准格式，可利用key来判断属性字段的顺序
     */
     romatFeaAttr: function (feature){
    fromatFeaAttr: function (feature) 
      if (feature.attributes) attributes;
        attr.lastStyle && delete attr.lastStyle;
        attr.updated && delete attr.updated;
        var markerHashOld = {
            title: true,
          description: true
          description: true,
        if (attr.properties && attr.properties._smiportal_title !== undefined) {
            return feature;
          
        //兼容8C SP1版本以前的标注点
        var len = 0;
        for(var key in attr){
        for (var key in attr) 
          lenmarkerHashOld[key]) {
              var newKey = "_smiportal_" + key;
            var str = (attr[key] !== null && attr[key] !== undefined) ? attr[key] : attr.properties[key];
            var str =
              attr[key] !== null && attr[key] !== undefined
                ? attr[key]
               
            if (feature.attributes.properties === undefined) 
              feature.attributes.key = [];
              
            feature.attributes.properties[newKey] = str;
            feature.attributes.key.push(newKey);
            delete feature.attributes[key];
            if(len === 2){
            if (len === 2) ature;
          }
            
      }
    }
      return feature;
  },
    /**
     * 根据图层模型获取底图类型
     * @param layerModel
     * @returns {*}
     */
    getBaseLayerType:function(layerModel){
    getBaseLayerType: function (layerModel) 
      if(layerModel.get('type') === 'SUPERMAP_REST'){
      if (layerModel.get("type") === "SUPERMAP_REST") ();
        type = layerModel.get("title"
      } else ype = layerModel.get('type');
        type = layerModel.get("type"
        if (type === "CLOUD") t('identifier') === 'blue-black'){
          if (layerModel.get("identifier") === "blue-black") 
            type = type + "_BLACK"
          e if(type === 'GOOGLE'){
        } else if (type === "GOOGLE") tifier') === 'china'){
          if (layerModel.get("identifier") === "china") 
            type = type + "_CN"
      }
    }
      return type;
  },
    assembleProperty: function (titleArray,value) {
    assembleProperty: function (titleArray, 
      var dataArray = [],
        e.length; i++) {
      for (var i = 0; i <  = value[i];
        var obj = {};
        if(rowData.length === 0 || (rowData.length === 1 && rowData[0] === "")) continue;
        if (rowData.length === 0 || (rowData.length === 1 && rowData[0] === ""))
         
        for (var j = 0; j < leArray[j];
          title = title && title.replace(/\ufeff/gi,'');
          title = title && title.replace(/\ufeff/gi, ""
      }
        dataArray.push(obj);
        
      return dataArray;
      
    assembleFeature: function (dataPrpertyArray,lonLatField,success,context) {
    assembleFeature: function (
      dataPrpertyArray,
      lonLatField,
      success,
      context
    ) {
      var features = = lonLatField.lon,
          latFiled = lonLatField.lat;
    for (var k=0; k<dataPrpertyArray.length; k++){
      for (var k = 0; k < dataPrpertyArray.length; k++) 
        var points=[], lonlatObject={},
        var points = [],
          lonlatObject = 
              type: "Feature"
            type: "Feature",
          },
            type: "point"
            type: "point",
          atObject.x = dataProperty[lonFiled];
        lonlatObject.y = dataProperty[latFiled];
        if(!lonlatObject.x || !lonlatObject.y || lonlatObject.x === "" || lonlatObject.y === "") continue;
        if (
          !lonlatObject.x ||
          !lonlatObject.y ||
          lonlatObject.x === "" ||
          lonlatObject.y === ""
        )
          continue;
        geometry.points = points;
        feature.geometry = geometry;
        feature.attributes = dataProperty;
        features.push(feature);
    }
      this.removeLonLatFiled(features,dataProperty,lonFiled,latFiled);
      this.removeLonLatFiled(features, dataProperty, lonFiled, 
             success.call(context, features);
        
      
    /**
     * 专题图图层，文件上传的，将经纬度字段过滤
     * @param features
     * @param newTitleArray
     * @param lonFiled
     * @param latFiled
     */
    removeLonLatFiled: function (features,newTitleArray,lonFiled,latFiled) {
    removeLonLatFiled: function (features, newTitleArray, lonFiled, 
      if   return newTitleArray;
    }
      for(var j =0; j<features.length; j++) {
      for (var j = 0; j < es = features[j].attributes;
        for(var title in attributes) {
        for  if(title === lonFiled || title === latFiled) {
          if   delete attributes[title];
            
          
        
      var temporaryArray = [];
      for(var i=0; i<newTitleArray.length; i++) {
      for (var i = 0; i < Array[i] === lonFiled || newTitleArray[i] === latFiled) {
        if else {
            temporaryArray.push(newTitleArray[i]);
      }
        
      return temporaryArray;
      
    /**
     * 获取用户的默认的key
     * @param success
     */
     etPrivateKey:function(success) {
    getPrivateKey: function 
      var keyUrl = this.getRootUrl() + "web/mycontent/keys/default.json";
      if (this.privateKey) {
          success && success(this.privateKey);
        se {
          this.sendRequest(keyUrl, "GET", "json", null, function (data) {
        this.sendRequest(
          keyUrl,
          "GET",
          "json",
          null,
         Result : '';
            var key = data.customResult ? data.customResult : ""
            success && success(key);
            unction (errorRes) {
          },
           me.showWarningMessage(errorRes.error.errorMsg);
            
          }
        
  },
    /**
     * 同步设置我的数据的权限
     * @param dataInfo
     * @param authorizeSettings
     * @param success
     * @param failed
     * @param scope
     */
    synMyDatasAuthorizeSetting:function(dataInfo, authorizeSettings, success, failed, scope){
    synMyDatasAuthorizeSetting: function (
      dataInfo,
      authorizeSettings,
      success,
      failed,
      scope
    ) {
      if(_.isArray(dataInfo)){
      if (_.isArray(dataInfo)) 
        e{
      } else ar layerModels = dataInfo.get('layers');
        var layerModels = dataInfo.get("layers"rs(layerModels);
    }
      var settings = {"ids":dataIds,"entities":[]};
      var settings = { ids: dataIds, entities: [] ength > 0){
      if (authorizeSettings && authorizeSettings.length > 0) n;i++){
        for (var i = 0, len = authorizeSettings.length; i < len; i++) s[i];
          var entity = {},
            authorizeSetting){
          for (var attr in authorizeSetting) {
            if (attr === "permissionType")  = 'DOWNLOAD';
              entity.dataPermissionType = "DOWNLOAD"
            } else ntity[attr] = authorizeSetting[attr];
              
            
          settings.entities.push(entity);
      }
        
      //{"entityType":"USER","entityName":"GUEST","dataPermissionType":"DOWNLOAD"}
      var url = this.getRootUrl() + "web/mycontent/datas/sharesetting.json";
      this.sendRequest(url, "PUT", "json", JSON.stringify(settings), function(data) {
      this.sendRequest(
        url,
        "PUT",
        "json",
        JSON.stringify(settings),
        function 
          success && success.call(scope || window, 
        },
        function (err) ailed.call(scope || window,err);
          failed && failed.call(scope || window, 
        }
      
    /**
     * 通过图层来获取url及对应的数据的id
     * @param layerModels
     * @returns {{urls: Array, dataIds: Array}}
     */
     etUploadDataIdsFromLayers:function(layerModels){
    getUploadDataIdsFromLayers: function (layerModels) 
      var urls = [],
       ex = /datas\/(\d+)\/content\.json/;
      layerModels.each(function(layerModel){
      layerModels.each(function (layerModel) ayerModel.isGraphicLayer() || layerModel.isFeatureLayer()){
        if (
          layerModel.isThemeLayer() ||
          layerModel.isGraphicLayer() ||
          layerModel.isFeatureLayer()
        ) {
          var isAddFile = layerModel.get("isAddFile"),
            url = layerModel.get("url"
          if (isAddFile && url) .match(dataIdRegrex);
            urls.push(urls);
            dataIds.push(parseInt(result[1]));
            
      }
        
      return dataIds;
  },
    /**
     * 还原logo的URL地址
     * @param url
     * @returns {*}
     */
     eplaceUrlPlaceHolder: function (url){
    replaceUrlPlaceHolder: function (url)  -1){
      if (url.indexOf("{portalRoot}") != -1)  this.getRootUrl().replace("manager/", ""));
        url = url.replace(
          "{portalRoot}",
          this.getRootUrl().replace("manager/", "")
        );
      url = url.replace(/(^http:)|(^https:)/,'');
      url = url.replace(/(^http:)|(^https:)/, ""
      
    //清空文件域，参数为Dom 对象
    cleanFileSelect: function (obj, fuc) {
        obj.val('');  //仅对ie11 及以上较新浏览器有作用
      obj.val("");cument.all ? true : false;
      if(isIE) {
      if   var objectClone = obj.clone();
        obj.after(objectClone);
        obj.remove();
        objectClone.on("change", function() {
        objectClone.on("change", function 
              fuc.call();
            
          
    }
      
    /**
     * 数组排序
     * @param arr 数组
     * @param isInvert  是否倒序排序,true为倒序  false和默认为正序
     * @returns {*}  排序后数组
     */
     ortArray: function (arr,isInvert) {
    sortArray: function (arr, 
      if   return arr.sort(this.invertedSort);
        se {
          return arr.sort(this.positiveSort);
        
      
    //正序
    positiveSort: function (a,b) {
    positiveSort: function (a, 
      return a - 
    //倒序
    invertedSort: function (a,b) {
    invertedSort: function (a, 
      return b - 
    /**
     * 将指定的div截取成一张图片
     * @param ele    $(dom)
     * @param callback 回调函数
     * @param context 调用回调函数的作用域(this),默认是window;
     */
     creenCut: function (ele,cavansSize,callback, context) {
    screenCut: function (ele, cavansSize, 
          html2canvas(ele, {
            allowTaint:true,
          allowTaint: alse,
          taintTest: ansSize.width || ele.outerWidth(),
          height: cavansSize.height || ele.outerHeight(),
          onrendered: function (canvas) {
            /*  var src = canvas.toDataURL();
              var img = new Image();
                                img.src = src;
                                img.onload = function() {

                                }*/
                                _.isFunction(callback) && callback.call(context || window, canvas);

          },
        });
      }     _.isFunction(callback) && callback.call(context || window, null);
    }
      
    uploadFileToMyData:function (metaData, fileElementId, success, failed, context) {
    uploadFileToMyData: function (
      metaData,
      fileElementId,
      success,
      failed,
      context
    ) {
      metaData = JSON.stringify(metaData);
      var uploadIdUrl  = host + "web/mycontent/datas.json";
      var uploadIdUrl
      return this.sendRequest(uploadIdUrl, "POST", "json", metaData, function(data) {
      return this.sendRequest(
        uploadIdUrl,
        "POST",
        "json",
        metaData,
        function 
          if(dataId) {
          if   var url = host + "web/mycontent/datas/" + dataId + "/upload.json";
            return $.ajaxFileUpload({
                url: url,
              dataType: "json",
              method: "POST",
              secureuri: false,
              fileElementId: fileElementId,
              success: function () {
                  success && success.call(context, host + "web/datas/"+ dataId + "/content.json?&currentPage=1&pageSize=9999999");
                success &&
                  success.call(
                    context,
                    host +
                      "web/datas/" +
                      dataId +
                      "/content.json?&currentPage=1&pageSize=9999999"
                  );
            },
              error: function (e) {
                  failed && failed.call(context ,e);
                failed && failed.call(context, 
              },
            e{
          } else ailed && failed.call(context);
            
          }
        },nction(e) {
        function && failed.call(context ,e);
          failed && failed.call(context, 
        }
      
    /**
     * 上传文件到指定文件夹
     * @param id
     * @param success
     * @param faild
     */
    uploadFileToDirName: function (id,success,faild) {
    uploadFileToDirName: function (id, success, irectoryName ? window.mapViewerConfig.directoryName : MapviewerConfig.directoryName;
      var dirName = window.mapViewerConfig.directoryName
        ? window.mapViewerConfig.directoryName
       
      var dirUrl = this.getRootUrl() + "web/directories/resources.json"
          basicDirInfo:{
        basicDirInfo: 
          id: Name:dirName,
          dirName: 'DATA',
          dirType: "DATA"
          dirLevel: Id:null,
          parentDirId: rue
          isPersonal: true,
        dirResource:{
        dirResource: Id:id
          resourceId: id,
        },
      datas = JSON.stringify(datas);
      this.sendRequest(dirUrl, "POST", "json", datas, success, faild);
  },
    uploadJsonToMyData: function(metaData, json, success, failed, context){
    uploadJsonToMyData: function (metaData, json, success, failed, context) 
      var host = this.getRootUrl();
      metaData = JSON.stringify(metaData);
      var uploadIdUrl  = host + "web/mycontent/datas.json";
      var uploadIdUrlRequest(uploadIdUrl, "POST", "json", metaData, function(data) {
      return this.sendRequest(
        uploadIdUrl,
        "POST",
        "json",
        metaData,
        function 
          if(dataId) {
          if   json = JSON.stringify(json);
            var url = host + "web/mycontent/datas/" + dataId + "/upload.json";
            return me.sendRequest(url, "POST", "json", json, function() {
            return me.sendRequest(
              url,
              "POST",
              "json",
              json,
              function  dataId + "/content.json?&currentPage=1&pageSize=9999999");
                success &&
                  success.call(
                    context,
                    host +
                      "web/datas/" +
                      dataId +
                      "/content.json?&currentPage=1&pageSize=9999999"
                  );
            }, function(e){
              },
              function (e) failed.call(context,e);
                failed && failed.call(context, 
              }
            {
          } else ailed && failed.call(context);
        }
          unction(e) {
        },
        function && failed.call(context ,e);
          failed && failed.call(context, 
        }
      
    updateToMyData: function(url, fileName, updateData, success, failed, context){
    updateToMyData: function (
      url,
      fileName,
      updateData,
      success,
      failed,
      context
    ) {
      url = url.split('web/datas/')[1];
      url = url.split("web/datas/"-9]\d*/gi);
      var dataId = parseInt(result[0]);
      var updataUrl = host + 'web/mycontent/datas/' + dataId + '/update.json?fileName=' + fileName + '&dataType=JSON';
      var updataUrl =
        host +
        "web/mycontent/datas/" +
        dataId +
        "/update.json?fileName=" +
        fileName +
        "&dataType=JSON"
      return this.sendRequest(updataUrl, "POST", "json", updateData, function() {
      return this.sendRequest(
        updataUrl,
        "POST",
        "json",
        updateData,
        function ntent.json?&currentPage=1&pageSize=9999999");
          success &&
            success.call(
              context,
              host +
                "web/datas/" +
                dataId +
                "/content.json?&currentPage=1&pageSize=9999999"
            );
        },
        function && failed.call(context, e);
      })
        }
      );
    toGeoJSON: function(features){
    toGeoJSON: function (features) e(features);
  },
    toFeatures: function(geojson){
    toFeatures: function (geojson) (geojson);
  }
    },
  
